import cv2
import numpy as np
import matplotlib.pyplot as plt

def laplacian_sharpening_demo(image_path, alpha=1.0):
    # 1. 加载图像
    img_bgr = cv2.imread(image_path)
    if img_bgr is None:
        print("Error: Could not load image.")
        return

    img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)

    # 2. (可选) 模拟模糊，让锐化效果更明显
    # blurred_img_gray = cv2.GaussianBlur(img_gray, (3, 3), 0)
    # img_to_process = blurred_img_gray
    img_to_process = img_gray # 默认直接处理原灰度图

    # 3. 计算拉普拉斯响应
    # cv2.CV_64F 是为了避免数据溢出，因为拉普拉斯结果可能有负值
    laplacian = cv2.Laplacian(img_to_process, cv2.CV_64F)

    # 4. 叠加锐化：核心！
    # 将laplacian转换为8位无符号整数，以便与原图叠加
    # 注意：拉普拉斯结果可能包含负值，直接转换为uint8会截断，
    # 但在这里我们直接将结果加减到原图，所以需要一些转换技巧。
    # 常用方法：原始图像 - alpha * laplacian (或 原始图像 + alpha * abs(laplacian)等)
    # 这里我们采用一种更直观的叠加方式：
    # 锐化后的图像 = 原始图像 + alpha * (原始图像 - 模糊后的图像)  -- 这种是Unsharp Mask
    # 或者直接： 锐化后的图像 = 原始图像 + alpha * laplacian  -- 这是拉普拉斯增强
    # 因为拉普拉斯在高频处有正负响应，直接加减需要处理好符号。
    # 更安全的做法是：将拉普拉斯结果映射到0-255，或者进行混合操作

    # 为了简单演示，我们采用一个常见的拉普拉斯锐化公式：
    # sharpened = original + k * laplacian
    # 这里的k通常是负数，或者通过原始图 - laplacian来实现
    # 因为拉普拉斯算子会使边缘处的像素值“变小”，加一个负号才能增大对比度
    sharpened_img = np.uint8(np.clip(img_to_process - alpha * laplacian, 0, 255))

    # 5. 可视化结果
    plt.figure(figsize=(15, 6))

    plt.subplot(1, 3, 1)
    plt.imshow(img_gray, cmap='gray')
    plt.title('Original Grayscale Image')
    plt.axis('off')

    plt.subplot(1, 3, 2)
    # 将拉普拉斯结果标准化到0-255以便显示
    laplacian_display = cv2.normalize(laplacian, None, 0, 255, cv2.NORM_MINMAX)
    laplacian_display = np.uint8(laplacian_display)
    plt.imshow(laplacian_display, cmap='gray')
    plt.title('Laplacian Response (Edges/Details)')
    plt.axis('off')

    plt.subplot(1, 3, 3)
    plt.imshow(sharpened_img, cmap='gray')
    plt.title(f'Sharpened Image (alpha={alpha})')
    plt.axis('off')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    # --- 如何运行Demo ---
    # 确保你有一张名为 'test_image.jpg' 的图片在当前目录下
    # 或者替换成你自己的图片路径
    # laplacian_sharpening_demo('test_image.jpg', alpha=0.5) # 尝试不同的alpha值

    # 为了直观演示“原罪”，你可以尝试：
    # 1. 在图像中加入一些高斯噪声（np.random.normal）
    # 2. 观察锐化后噪声的变化

    # 你可以替换成自己的图片路径
    image_path = './gray_filter_laplacian/test1.jpg'
    alpha = 0.8
    laplacian_sharpening_demo(image_path, alpha)
